package craky.keeper;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.Icon;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import craky.componentc.JCCheckBoxMenuItem;
import craky.componentc.JCMenu;
import craky.componentc.JCMenuItem;
import craky.componentc.JCRadioButtonMenuItem;
import craky.keeper.category.CategoryListDialog;
import craky.keeper.user.UserListDialog;
import craky.keeper.util.KeeperUtil;
import craky.util.Config;
import craky.util.UIUtil;

public class KeeperMenu extends JCMenu implements ActionListener,
		PopupMenuListener {
	private static final long serialVersionUID = -7383303149120649519L;
	private static final Icon ICON = KeeperUtil.getIcon("menu_button_icon.png");

	private static final Image ROLLOVER_IMAGE = KeeperUtil.getImage(
			"common_button_rollover_bg.png", true);

	private static final Image PRESSED_IMAGE = KeeperUtil.getImage(
			"common_button_pressed_bg.png", true);
	private KeeperApp keeper;
	private KeeperMgr mgr;
	private Config config;
	private JMenuItem miExport;
	private JMenuItem miExit;
	private JMenuItem miUser;
	private JMenuItem miCategory;
	private JMenuItem miTitleOpaque;
	private JMenuItem miShowDetail;
	private JMenuItem miShowFind;
	private JMenuItem miSetting;
	private JMenuItem miAbout;

	public KeeperMenu(KeeperApp keeper, KeeperMgr mgr) {
		this.keeper = keeper;
		this.mgr = mgr;
		this.config = keeper.getConfig();
		setToolTipText("主菜单");
		setPreferredSize(new Dimension(20, 20));
		setShowWhenRollover(false);
		init();
		getPopupMenu().addPopupMenuListener(this);
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				KeeperMenu.this.getModel().setRollover(true);
			}

			@Override
			public void mouseExited(MouseEvent e) {
				KeeperMenu.this.getModel().setRollover(false);
			}
		});
	}

	private void init() {
		JCMenu meFile;
		add(meFile = new JCMenu("文件"));
		JCMenu meView;
		add(meView = new JCMenu("查看"));
		JCMenu meAdvanced;
		add(meAdvanced = new JCMenu("高级"));
		add(this.miSetting = createMenuItem("设置(S)", 0, 0, 'S',
				MenuItemType.MenuItem));
		add(this.miAbout = createMenuItem("关于(A)", 0, 0, 'A',
				MenuItemType.MenuItem));
		meFile.add(this.miExport = createMenuItem("导出为CSV(E)...", 0, 0, 'E',
				MenuItemType.MenuItem));
		meFile.addSeparator();
		meFile.add(this.miExit = createMenuItem("退出(X)", 0, 0, 'X',
				MenuItemType.MenuItem));
		meAdvanced.add(this.miUser = createMenuItem("用户管理(U)", 0, 0, 'U',
				MenuItemType.MenuItem));
		meAdvanced.add(this.miCategory = createMenuItem("消费类别(C)", 0, 0, 'C',
				MenuItemType.MenuItem));
		meView.add(this.miTitleOpaque = createMenuItem("标题栏明(T)", 0, 0, 'T',
				MenuItemType.CheckBoxMenuItem));
		meView.add(this.miShowDetail = createMenuItem("显示明细(D)", 0, 0, 'D',
				MenuItemType.CheckBoxMenuItem));
		meView.add(this.miShowFind = createMenuItem("显示查找(F)", 70, 2, 'F',
				MenuItemType.CheckBoxMenuItem));
		this.miExport.setIcon(KeeperUtil.getIcon("export.png"));
		this.miExit.setIcon(KeeperUtil.getIcon("menu_exit.png"));
		this.miUser.setIcon(KeeperUtil.getIcon("menu_user.png"));
		this.miCategory.setIcon(KeeperUtil.getIcon("menu_category.png"));
		this.miSetting.setIcon(KeeperUtil.getIcon("menu_setting.png"));
		this.miAbout.setIcon(KeeperUtil.getIcon("logo_16.png"));
		meAdvanced.setVisible(this.keeper.getCurrentUser().getPurview() == 0);
	}

	private JMenuItem createMenuItem(String text, int key, int modifiers,
			char mnemonic, MenuItemType type) {
		JMenuItem item;

		if (type == MenuItemType.RadioMenuItem) {
			item = new JCRadioButtonMenuItem(text);
		} else {

			if (type == MenuItemType.CheckBoxMenuItem) {
				item = new JCCheckBoxMenuItem(text);
			} else {
				item = new JCMenuItem(text);
			}
		}
		if (key != 0) {
			item.setAccelerator(KeyStroke.getKeyStroke(key, modifiers));
		}

		if (mnemonic != 0) {
			item.setMnemonic(mnemonic);
		}

		item.addActionListener(this);
		return item;
	}

	@Override
	protected void paintComponent(Graphics g) {
		int width = getWidth();
		int height = getHeight();
		int iconWidth = ICON.getIconWidth();
		int iconHeight = ICON.getIconHeight();

		if (getModel().isSelected()) {
			UIUtil.paintImage(g, PRESSED_IMAGE, new Insets(2, 2, 2, 2),
					new Rectangle(0, 0, width, height), this);
		} else if (getModel().isRollover()) {
			UIUtil.paintImage(g, ROLLOVER_IMAGE, new Insets(2, 2, 2, 2),
					new Rectangle(0, 0, width, height), this);
		}

		ICON.paintIcon(this, g, (width - iconWidth) / 2,
				(height - iconHeight) / 2);
	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		if (source == this.miExport) {
			this.mgr.export();
		} else if (source == this.miExit) {
			this.keeper.exit();
		} else if (source == this.miTitleOpaque) {
			this.mgr.setTitleOpaque(!Boolean.valueOf(
					this.config.getProperty("Title_Opaque", "false"))
					.booleanValue());
		} else if (source == this.miShowDetail) {
			this.mgr.showDetail(!Boolean.valueOf(
					this.config.getProperty("Show_Detail", "true"))
					.booleanValue());
		} else if (source == this.miShowFind) {
			this.mgr.showFind(!Boolean.valueOf(
					this.config.getProperty("Show_Find", "true"))
					.booleanValue());
		} else if (source == this.miUser) {
			new UserListDialog(this.keeper);
		} else if (source == this.miCategory) {
			new CategoryListDialog(this.keeper);
		} else if (source == this.miSetting) {
			this.mgr.setting();
		} else if (source == this.miAbout) {
			new AboutDialog(this.keeper);
		}
	}

	public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
		this.miTitleOpaque.setSelected(!Boolean.valueOf(
				this.config.getProperty("Title_Opaque", "false"))
				.booleanValue());
		this.miShowDetail.setSelected(Boolean.valueOf(
				this.config.getProperty("Show_Detail", "true")).booleanValue());
		this.miShowFind.setSelected(Boolean.valueOf(
				this.config.getProperty("Show_Find", "true")).booleanValue());
	}

	public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
	}

	public void popupMenuCanceled(PopupMenuEvent e) {
	}

	private static enum MenuItemType {
		MenuItem, RadioMenuItem, CheckBoxMenuItem;
	}
}